function MYPromise(executor) {
    // 添加属性
    this.PromiseState = 'pending'  // 状态值
    this.PromiseResult = null // 结果值
    // 因为实参函数内this指向的是wendow 所以需要保存this的指向值
    const self = this
    // 声明属性 接受then方法的回调函数
    this.callback = []
    //定义resolve实参函数 
    function resolve(data) {
        // 判断状态 因为Promise的状态值只能更改一次 如果已经修改了状态值 直接return
        if (self.PromiseState !== 'pending') return
        // 修改成功的状态值 
        self.PromiseState = 'fulfilled' // resolved
        // 修改成功的结果值 
        self.PromiseResult = data
        // 调用成功的回调函数 遍历回调数组
        // then方法是异步的 添加一个定时器 模拟异步
        setTimeout(() => {
          self.callback.forEach(i => {
            i.onResolved(data)
             }) 
        })
        
    }
    // 定义reject实参函数
    function reject(data) {
        // 判断状态 因为Promise的状态值只能更改一次 如果已经修改了状态值 直接return
        if (self.PromiseState !== 'pending') return
        // 修改失败的状态值 
        self.PromiseState = 'rejectd' // rejectd
        // 修改成功的结果值 
        self.PromiseResult = data
        // 调用失败的回调函数 遍历回调数组
        // then方法是异步的 添加一个定时器 模拟异步
        setTimeout(() => {
            self.callback.forEach(i => {
            i.onRejectd(data)
            })
        })
        
    }

    // throw 抛出异常改变状态
    try {
        // 同步调用 【执行器函数】 接收传过来的参数
        executor(resolve, reject)
    } catch (err) {
        reject(err)
    }

}

//添加then方法
MYPromise.prototype.then = function (onResolved, onRejectd) {
    // 改变this指向
    const self = this
    // 因为catch可以异常穿透  判断回调函数不为 undefined 而是一个funtion
    // 设置一个默认值
    if (typeof onRejectd !== 'function') {
        onRejectd = reason => {
            throw reason
        }
    }
    if (typeof onResolved !== 'function') {
        onResolved = value => value
    }
    return new MYPromise((resolve, reject) => {
        // 因为处理代码都写的一样 除了回调函数不一样 封装一个函数 
        function callback(onType) {
            // 用 try 捕获抛出异常
            try {
                // 实参是Promise实例返回的结果值
                const Result = onType(self.PromiseResult)
                // 判断then返回的是不是一个Promise类型对象 
                if (Result instanceof MYPromise) {
                    Result.then(res => {
                        resolve(res)
                    }, rej => {
                        reject(rej)
                    })
                } else {
                    // 如果不是Promise类型的对象 直接调成功的Promise
                    resolve(Result)
                }
            } catch (err) {
                reject(err)
            }
        }
        // 判断状态是否为成功
        if (this.PromiseState === 'fulfilled') {
            // then方法是异步的 添加一个定时器 模拟异步
            setTimeout(() => {
                callback(onResolved)
            })
        }
        // 判断状态是否为失败
        if (this.PromiseState === 'rejectd') {
            // then方法是异步的 添加一个定时器 模拟异步
            setTimeout(() => {
                callback(onRejectd)
            })
        }
        // 判断状态是否为进行中 处理异步任务 保存回调函数
        if (this.PromiseState === 'pending') {
            // 考虑到会执行多个回调函数 所以用push
            this.callback.push({
                onResolved: () => {
                    callback(onResolved)
                }
                ,
                onRejectd: () => {
                    callback(onRejectd)
                }
            })
        }
    })
}

// 添加catch方法 接收失败的回调 
MYPromise.prototype.catch = function (onRejectd) {
    // 返回一个Promise 因为then方法功能都实现了 
    return this.then(undefined, onRejectd)
}

// 添加Promise.resolve方法 不输入实例对象身上的方法 属于函数方法
MYPromise.resolve = function(value){
    // 返回一个Promise
    return new MYPromise((resolve,reject) => {
        // 判断是否为一个Promise
        if(value instanceof MYPromise){
            value.then(res => { resolve(res) }, rej => { reject(rej) })
        }else{
            resolve(value)
        }
    })
}

// 添加Promise.reject方法 只返回失败的Promise 失败的结果是传递的参数
MYPromise.reject = function(reason){
    // 返回一个失败的Promise
    return new MYPromise((resolve,reject) => {
        reject(reason)
    })
}



// 添加Promise.all 方法 等待所有Promise执行完成 返回一个Promise对象 一个失败全部失败 返回的结果值是传递参数的数组
MYPromise.all = function(Result){
    // 返回一个Promise 结果值是n个Promise结果值的数组
    return new MYPromise((resolve,reject) => {
        // 声明一个数组 接收n个Promise的结果值
        var arr = []
        // 声明一个变量 接收执行次数
        var count = 0
        // 循环遍历Resut
        for(let i = 0 ; i < Result.length ; i++){
            Result[i].then(res => {
                // 得知状态是成功 每一个Promise都成功 自增
                count++
                // 将当前成功的Promise存入到arr数组
                arr[i] = res
                if(count ===  Result.length){
                    //修改状态
                    resolve(arr)
                }
            },rej=> {
                reject(rej)
            })
        }
    })
}

// 添加Promise.race方法 等待n个Promise执行 谁先执行完就返回谁 
MYPromise.race = function(Result){
    return new MYPromise((resolve,reject) => {
        for(let i = 0; i < Result.length ; i++){
            Result[i].then(res => {
                // 将状态修改为【成功】
                resolve(res)
            },rej => {
                // 将状态修改为【失败】
                reject(rej)
            })
        }
    })
}

